﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.IO;
using System.Windows.Media;
using System.Reflection;
using System.Security.Principal;
using System.Text.RegularExpressions;

using Idlesoft.Utils;

namespace Idlesoft.ShellAnywhere.Model
{	
	public class ShellAnywhereModel : IShellAnywhereModel
	{
		#region ctors
		public ShellAnywhereModel()
		{
			Shell psh = new Shell(@"C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe", "-i Text -Command -", "psh");
			Shell cmd = new Shell(@"C:\Windows\System32\cmd.exe", "cmd");

			_Username = Environment.UserName;
			_TargetsFile = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Targets.xml");

			List<string> targets = new List<string>(Common.FindFiles(Environment.GetFolderPath(Environment.SpecialFolder.System), SearchOption.TopDirectoryOnly, false, "*.exe"));
			targets.Add(_TargetsFile);

			if (!File.Exists(_TargetsFile))
				File.Create(_TargetsFile);

			_LaunchMgr = new LaunchMgr(OnStdOut, OnStdErr, new Shell[] { psh, cmd }, targets.ToArray() );
			_NavigationMgr = new NavigationMgr();

			ActionMgr = _LaunchMgr;
			HistoryMgr = new HistoryMgr();

			//static; will set for both the launch and navigation mgrs
			ActionMgr.CurrentDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

			_WaitTimeSpan = new TimeSpan(0, 0, 2);
		}
		#endregion ctors

		#region props
		//public Config Config { get; set; }
		public HistoryMgr HistoryMgr { get; internal set; }
		private Posture _Posture;
		public Posture Posture
		{
			get { return _Posture; }
			set
			{
				if (_Posture != value)
					PostureChanged(_Posture = value);
			}
		}
		private IActionMgr _ActionMgr;
		public IActionMgr ActionMgr
		{
			get { return _ActionMgr; }
			set
			{
				if (_ActionMgr != value)
				{					
					if (_ActionMgr != null)
						_ActionMgr.IsActive = false; //turn off old am
					if (value != null)
						value.IsActive = true; //turn on new am
					_ActionMgr = value;
				}
			}
		}

		#endregion props

		#region methods

		public void PostureChanged(Posture posture)
		{
			switch (posture)
			{
				case Posture.Launch:
				case Posture.Shell:
					ActionMgr = _LaunchMgr.SetPosture(posture);
					break;
				case Posture.Navigation:
					ActionMgr = _NavigationMgr;
					break;
			}
			ActionMgr.Update(ActionMgr.UserInput);
		}
		public void OnStdOut(string text)
		{
			if (OutputAppend != null)
				OutputAppend(Brushes.CornflowerBlue, text);
		}
		public void OnStdErr(string text)
		{
			if (OutputAppend != null)
				OutputAppend(Brushes.Red, text);
		}

		public void Init()
		{
			//_LaunchMgr.Init();
			//_NavigationMgr.Init();
		}
		public void End()
		{
			_LaunchMgr.End();
			_NavigationMgr.End();
		}
		#endregion methods

		#region events
		public event Action<List<IShellAction>, int> ShellActionsChanged
		{
			add
			{
				_LaunchMgr.ShellActionsChanged += value;
				_NavigationMgr.ShellActionsChanged += value;
			}
			remove
			{
				_LaunchMgr.ShellActionsChanged -= value;
				_NavigationMgr.ShellActionsChanged -= value;
			}
		}
		public event Action<Brush, string> OutputAppend;
		#endregion events

		#region fields
		private string _Username;
		private string _TargetsFile;

		private TimeSpan _WaitTimeSpan;

		private LaunchMgr _LaunchMgr;
		private NavigationMgr _NavigationMgr;
		#endregion fields
	}
}
